#include <iostream>
// 职责链模式，行为型模式，用于将请求传递给一个链中的若干个对象
// 哪个对象能处理就由哪个对象进行处理，不能处理则传递给下一个对象，和链表很相似

// 主要组成部分
// 处理器接口，定义处理请求的接口，
// 具体处理类，实现处理请求的内容
// 请求类，包含多个属性，决定哪个具体处理器处理哪个请求
// 客户端，组建处理链

// 1、定义处理者接口
// 加薪请求类
class RaiseRequest {
    public:
    RaiseRequest(const std::string& name,int money):name_(name),RaiseMoney_(money) {}
    // 获取请求加薪的人员名字
    const std::string& getName() const {
        return name_;
    }
    // 获取请求加薪的数字
    int getMoney() const {
        return RaiseMoney_;
    }
    private:
    std::string name_;
    int RaiseMoney_;
};

// 2、定义抽象处理者 薪水审批者父类
class ParsalApprover {
    public:
    ParsalApprover():m_nextChain_(nullptr) {}
    virtual ~ParsalApprover() {} // 做父类时析构函数应该为虚函数

    // 设置指向职责链的下一个审批者
    void setNextChain(ParsalApprover* next) {
        m_nextChain_ = next;
    }

    virtual void processRequest(const RaiseRequest& req) = 0;

    protected:
    // 找链中的下个对象并把请求投递给下个链中的对象
    void sendRequest2NextHandler(const RaiseRequest& req) {
        if(m_nextChain_) {
            // 把请求传递给下一个对象
            m_nextChain_->processRequest(req);
        }
        else {
            // 没有下一个对象，流程执行到这里应该结束
            std::cout << req.getName() << "的加薪要求为： " << req.getMoney() << "元，但是无人能够审批！" << std::endl;
        }
    }
    private:
    ParsalApprover* m_nextChain_; // 指向下一个审批者（对象）的多态指针（指向自身类型），每个都指向下一个，就会构成一个职责链
};

// 3、创建三个具体处理类 depManager_SA,CTO_SA,genManager_SA，每个类根据其规则处理请求

// 部门经理类
class depManager_SA : public ParsalApprover {
    public:
    void processRequest(const RaiseRequest& req) override{
        int salfigure = req.getMoney();
        if(salfigure <= 1000) {
            // 如果自己能够处理，则自己处理
            std::cout << req.getName() << "的加薪要求为： " << salfigure << "元，部门经理审批通过！" << std::endl;
        }
        else {
            sendRequest2NextHandler(req);
        }
    }

};

// 技术总监类
class CTO_SA : public ParsalApprover {
    public:
    void processRequest(const RaiseRequest& req) override{
        int salfigure = req.getMoney();
        if(salfigure > 1000 && salfigure <= 5000) {
            // 如果自己能够处理，则自己处理
            std::cout << req.getName() << "的加薪要求为： " << salfigure << "元，技术总监审批通过！" << std::endl;
        }
        else {
            sendRequest2NextHandler(req);
        }
    }

};

// 总经理类
class genManager_SA : public ParsalApprover {
    public:
    void processRequest(const RaiseRequest& req) override{
        int salfigure = req.getMoney();
        if(salfigure > 5000) {
            // 如果自己能够处理，则自己处理
            std::cout << req.getName() << "的加薪要求为： " << salfigure << "元，总经理审批通过！" << std::endl;
        }
        else {
            sendRequest2NextHandler(req);
        }
    }

};

int main () {
    std::cout << "hello 职责链模式" << std::endl;
    // （1）创建出职责链中包含的各个对象
    ParsalApprover* pzzlinkobj1 = new depManager_SA();
    ParsalApprover* pzzlinkobj2 = new CTO_SA();
    ParsalApprover* pzzlinkobj3 = new genManager_SA();

    // (2)将这些对象串在一起构成职责链
    pzzlinkobj1->setNextChain(pzzlinkobj2);
    pzzlinkobj2->setNextChain(pzzlinkobj3);
    pzzlinkobj3->setNextChain(nullptr);

    // (3)创建几位员工关于加薪的请求
    RaiseRequest emp1Req("张三",15000);
    RaiseRequest emp2Req("李四",3500);
    RaiseRequest emp3Req("王二",800);

    pzzlinkobj1->processRequest(emp1Req);
    pzzlinkobj1->processRequest(emp2Req);
    pzzlinkobj1->processRequest(emp3Req);

    // 释放资源
    delete pzzlinkobj1;
    delete pzzlinkobj2;
    delete pzzlinkobj3;

    return 0;
}